package com.jinzecloud.reportapproval.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.Pictures;
import com.jinzecloud.reportapproval.bean.VegetationRecordForm;
import com.jinzecloud.reportapproval.dto.AdminDto;
import com.jinzecloud.reportapproval.dto.AuditParam;
import com.jinzecloud.reportapproval.dto.DataStagingParam;
import com.jinzecloud.reportapproval.enums.AuditRoleEnums;
import com.jinzecloud.reportapproval.enums.StateEnum;
import com.jinzecloud.reportapproval.enums.TableEnums;
import com.jinzecloud.reportapproval.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.io.File;
import java.nio.file.StandardCopyOption;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.jinzecloud.reportapproval.mapper.SpeedOperationTableMapper;
import com.jinzecloud.reportapproval.bean.SpeedOperationTable;
import com.jinzecloud.reportapproval.service.SpeedOperationTableService;

import javax.servlet.http.HttpServletRequest;


@Service("speedOperationTableService")
public class SpeedOperationTableServiceImpl extends ServiceImpl<SpeedOperationTableMapper, SpeedOperationTable> implements SpeedOperationTableService {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private FileUploadUtil fileUploadUtil;

    private SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd"); // 原始格式


    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy 年 MM 月 dd 日");

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpeedOperationTable> page = this.page(
                new Query<SpeedOperationTable>().getPage(params),
                new QueryWrapper<SpeedOperationTable>().like("project_code", params.get("key")).orderByDesc("id")
        );

        return new PageUtils(page);
    }

    @Override
    public String viewPdf(Integer id) {
        SpeedOperationTable operationTable = getById(id);

        try {
            operationTable.setAssayData(sdf.format(inputFormat.parse(operationTable.getAssayData())));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(operationTable));
        if (StrUtil.isNotEmpty(data.getString("detectPeople"))) data.put("detectPeople", Pictures.ofUrl(data.getString("detectPeople")).size(30, 10).create());
        if (StrUtil.isNotEmpty(data.getString("recorders"))) data.put("recorders", Pictures.ofUrl(data.getString("recorders")).size(30, 10).create());
        if (StrUtil.isNotEmpty(data.getString("checkers"))) data.put("checkers", Pictures.ofUrl(data.getString("checkers")).size(30, 10).create());


        //word
        File tempFile = WordUtil.getWordFile("template/operation.docx", data, Configure.builder());

        if (tempFile == null) return null;
        String fileName = "作业速度测定记录表";
        String uploadDirectory = fileUploadUtil.getUploadFilePath("temp");
        String filePath = uploadDirectory + operationTable.getProjectCode() + fileName;
        String savePath = RequestUtils.getBasePath(request) + "upload/temp/" + operationTable.getProjectCode() +fileName;
        FileUtil.copyFile(tempFile, new File(filePath + ".docx"), StandardCopyOption.REPLACE_EXISTING);
        PDFUtil.WordToPdf(tempFile, new File(filePath + ".pdf"));

        update(new LambdaUpdateWrapper<SpeedOperationTable>().set(SpeedOperationTable::getWordPath, savePath + ".docx").set(SpeedOperationTable::getPdfPath, savePath + ".pdf").eq(SpeedOperationTable::getId, id));

        return RequestUtils.getBasePath(request) + "upload/temp/" + operationTable.getProjectCode() + fileName + ".pdf";
    }

    @Override
    public Object auditList(DataStagingParam param) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LambdaQueryWrapper<SpeedOperationTable> queryWrapper = new LambdaQueryWrapper<>();
        List<AdminDto> adminDto = AuditUtil.getAdminDto(authentication.getName());
        Set<Integer> roleSet = adminDto.stream().map(a -> StateEnum.getStateEnumByAuditRole(a.getRoleCode()).getState()).collect(Collectors.toSet());
        roleSet.remove(StateEnum.UN_SUBMIT.getState());
        queryWrapper.in(SpeedOperationTable::getStatus, roleSet);
        return page(new Page<>(param.getPageNo(), param.getPageSize()), queryWrapper);
    }

    @Override
    public R audit(AuditParam auditParam) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        List<AdminDto> adminDos = AuditUtil.getAdminDto(authentication.getName());
        if (CollectionUtil.isEmpty(adminDos)) return R.error("您没有审核权限！");
        SpeedOperationTable vegetationRecordForm = this.getById(auditParam.getId());
        int state = vegetationRecordForm.getStatus();
        if (!auditParam.isState()) {
            updateById(vegetationRecordForm.setStatus(StateEnum.APPROVAL_NOT_PASS.getState())
                    .setAuditOpinion(auditParam.getAuditOpinion())
                    .setAuditDate(DateUtil.date().toDateStr()));
            return R.ok();
        }
        StateEnum currentAuditState = AuditUtil.getStateText(TableEnums.SPEED_OPERATION_TABLE.getTableName(), state);
        Integer nextAuditStateIndex = AuditUtil.getNextAuditState(TableEnums.SPEED_OPERATION_TABLE.getTableName(), state, adminDos.stream().map(AdminDto::getRoleCode).toList());
        AdminDto adminDto = adminDos.stream().filter(a -> StrUtil.equals(a.getRoleCode(), currentAuditState.getAuditRole()))
                .findFirst().orElse(null);
        if (adminDto == null || nextAuditStateIndex == null) return R.error("您没有审核权限！");
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.CHECKER_PERSON.getCode())) vegetationRecordForm.setDetectPeople(adminDto.getAdSignature());
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.RECORDER.getCode())) vegetationRecordForm.setRecorders(adminDto.getAdSignature());
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.CHECKER.getCode())) vegetationRecordForm.setCheckers(adminDto.getAdSignature());
        vegetationRecordForm.setStatus(nextAuditStateIndex)
                .setAuditOpinion(auditParam.getAuditOpinion())
                .setAuditDate(DateUtil.date().toDateStr());
        updateById(vegetationRecordForm);
        return R.ok();
    }

    @Override
    public JSONObject speedOperationTableJson(String projectUuid) {
        SpeedOperationTable operationTable = getOne(new QueryWrapper<SpeedOperationTable>().eq("project_code", projectUuid));
        if (operationTable == null) return null;
        try {
            operationTable.setAssayData(sdf.format(inputFormat.parse(operationTable.getAssayData())));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(operationTable));

        return data;
    }

}
